LLM as Judge 在 Agentic 环境中的优化实现
本文档介绍 ROLL 框架中 LLM as Judge 在 Agentic 环境中的优化实现方案,包括系统架构、调用链路、配置方法和最佳实践。
概览
LLM as Judge 是一种使用大语言模型作为评判器来评估智能体响应质量的方法。在 Agentic 训练场景中,大规模环境实例并发执行 rollout 时,使用 LLM as Judge 计算 reward 会产生大量并发 LLM 请求,这对外部 LLM 服务的稳定性和吞吐量提出了巨大挑战。
为解决这一问题,ROLL 框架通过独立的 Reward Cluster 和高效的调度机制,实现了可扩展的本地化并行评估系统,避免了对外部服务的依赖,确保了训练过程的稳定性和可控性。
本文档以 DeepEyes 环境的 LLM as Judge 实现为例进行说明。对于其他需要使用 LLM as Judge 的环境,可以参考 env_manager 和 env 内的调用方式自定义实现。
核心优势
- 独立资源管理:Reward 模型与 Policy 模型分离,可独立分配 GPU 资源,避免资源竞争
- 本地化部署:通过本地 Reward Cluster 避免外部 API 依赖,保证服务稳定性和数据安全
- 高并发支持:通过 RequestScheduler 实现多环境并行的高效 reward 评估,支持环境并发扩展
- 统一接口设计:提供
generate_by_proxy统一工具函数,简化 LLM 调用逻辑,支持文本和多模态 - 灵活配置:支持多种推理后端(vLLM、SGLang)和自定义生成参数
应用场景
典型的 Agentic 训练场景:
- 环境规模:256个环境组,每组 4 个环境,共 1024个并发环境实例
- Rollout 频率:每个环境完成 episode 后调用 LLM Judge
- 并发压力:在 rollout 高峰期可能有 500+ 个环境同时请求 reward 评估
- 稳定性要求:训练过程不能因为外部 API 限流或超时而中断
通过本文档介绍的优化实现,可以有效应对上述挑战。
系统架构
整体架构
AgenticPipeline
├── Reward Cluster (可选,独立GPU资源)
│ ├── InferWorker (默认)
│ └── 支持 vLLM/SGLang 后端
│
├── Reward Scheduler (Ray Named Actor)
│ ├── 请求路由与负载均衡
│ ├── 并发控制
│ └── 请求追踪与清理
│
└── Environment Manager
├── llm_proxy: 用于 policy 推理
├── reward_proxy: 用于 LLM as Judge
└── env实例
└── 在 obtain_outcome_reward 中调用 reward_proxy
关键组件
1. Reward Cluster
位置: roll/pipeline/agentic/agentic_pipeline.py:88-98
Reward Cluster 是可选组件,仅在配置了 device_mapping 时创建:
self.reward = None
if (self.pipeline_config.reward is not None and
len(self.pipeline_config.reward.device_mapping) > 0):
self.reward = Cluster(
name=self.pipeline_config.reward.name,
worker_cls=self.pipeline_config.reward.worker_cls, # 默认 InferWorker
resource_manager=self.resource_manager,
worker_config=self.pipeline_config.reward,
)
Worker Class 默认配置: roll/pipeline/agentic/agentic_config.py:287
- 默认使用
InferWorker作为推理引擎,复用ActorInfer Worker实现 - 支持 vLLM、SGLang等多种后端
2. Reward Scheduler (Ray Named Actor)
位置: roll/pipeline/agentic/agentic_pipeline.py:112-125
Reward Scheduler 作为 Ray Named Actor 创建,供所有环境管理器共享访问:
self.reward_scheduler = RequestScheduler.options(
name=f"RewardScheduler-{self.pipeline_config.reward.name}",
get_if_exists=True,
namespace=RAY_NAMESPACE,
scheduling_strategy=NodeAffinitySchedulingStrategy(...)
).remote(
infer_cluster=self.reward,
pipeline_config=self.pipeline_config,
resource_manager=self.resource_manager,
)
核心功能:
- 智能路由: 使用最少负载路由算法分配请求到不同的 DP rank
- 粘性路由: 同一环境的请求固定路由到同一 worker(利于 KV cache)
- 请求追踪: 维护
request_id到 worker 的映射关系
3. Reward Proxy
位置: roll/pipeline/agentic/env_manager/vl_traj_env_manager.py:85-109
环境管理器通过 Ray 获取 Reward Scheduler 并创建 Reward Proxy:
# 从 Ray 获取 reward scheduler (Named Actor)
if self.pipeline_config.reward:
self.reward_scheduler = ray.get_actor(
name=f"RewardScheduler-{pipeline_config.reward.name}",
namespace=RAY_NAMESPACE
)
# 创建 reward proxy
self.reward_proxy = create_llm_proxy(
generate_scheduler=self.reward_scheduler,
llm_proxy_config=pipeline_config.reward.llm_proxy,
tokenizer=self.reward_tokenizer,
env=None,
)
Proxy 工厂函数: roll/pipeline/agentic/llm_proxy/__init__.py:11
- 支持多种 proxy 类型:
policy、openai、random - 通过注册机制实现可扩展性
- 训练验证过policy设置功能正常,基于外部部署的大模型服务可使用openai proxy,注意对并发的挑战
4. 统一工具函数 generate_by_proxy
位置: roll/pipeline/agentic/llm_proxy/proxy_utils.py:18-170
这是env调用的核心组件,提供统一的 LLM 调用接口:
def generate_by_proxy(
messages: List[Dict[str, Any]],
tokenizer: PreTrainedTokenizer,
proxy: BaseLLMProxy,
enable_thinking: bool = False,
generation_config: Optional[Dict[str, Any]] = None,
collator: Optional[Any] = None,
mm_data: Optional[Dict[str, Any]] = None,
src_rank: Optional[int] = None,
) -> Optional[str]
核心特性:
- 统一接口: 无论文本还是多模态,都使用相同的调用方式
- 自动格式化: 使用
tokenizer.apply_chat_template格式化消息 - 多模态支持: 通过
collator参数支持图像/视频输入 - thinking 机制: 支持 DeepSeek、Qwen 等模型的思考链
- 路由控制: 通过
src_rank参数实现粘性路由 - 错误处理: 返回
None表示推理失败,由调用方处理